﻿#include "tablewidget.h"
#include "common/logger/logger.h"
#include "control_sample/qtpropertybrowser/qtbuttonpropertybrowser.h"
#include "control_sample/qtpropertybrowser/qteditorfactory.h"
#include "control_sample/qtpropertybrowser/qtpropertymanager.h"
#include "control_sample/qtpropertybrowser/qttreepropertybrowser.h"
#include "control_sample/qtpropertybrowser/qtvariantproperty.h"
#include "controls/table/cxitable.h"
#include "generictablemodel.h"
#include "paint.h"
#include "spdlog/details/os.h"
#include "ui_TableWidget.h"

#include <QFont>
#include <QVBoxLayout>

using namespace cxitable;

TableWidget::TableWidget(QWidget* parent)
	: QWidget(parent), ui(new Ui::TableWidget)
{
	ui->setupUi(this);
	_init();
}

TableWidget::~TableWidget()
{
	delete ui;
}

void TableWidget::initDefaultTable()
{
	// ========== 初始化左侧表格 ==========
	auto cxiTable = ui->cxiTable;
	QList<GridColumnConfig> headers;
	headers.append(GridColumnConfig("id", "ID"));
	headers.append(GridColumnConfig("name", "姓名")); {
		GridColumnConfig col("gender", "性别");
		col.visible = false;
		headers.append(col);
	}
	headers.append(GridColumnConfig("age", "年龄"));
	headers.append(GridColumnConfig("medicalRecordNo", "病历号"));
	headers.append(GridColumnConfig("birthDate", "出生日期"));
	headers.append(GridColumnConfig("contactNumber", "联系方式"));
	headers.append(GridColumnConfig("address", "地址"));
	headers.append(GridColumnConfig("bloodType", "血型"));
	headers.append(GridColumnConfig("allergies", "过敏史"));
	headers.append(GridColumnConfig("medicalHistory", "既往病史")); {
		GridColumnConfig col("createTime", "创建时间");
		col.width = 300;
		col.readOnly = true;
		col.textAlignment = Qt::AlignCenter;
		col.headForeColor = Qt::red;
		col.isBold = true;
		headers.append(col);
	} {
		GridColumnConfig col("updateTime", "更新时间");
		col.format = "yyyy-MM-dd hh:mm";
		col.autoWidth = true;
		col.floatCellContent = true;
		col.textAlignment = Qt::AlignRight;
		col.headForeColor = Qt::red;
		col.headBackColor = Qt::blue;
		headers.append(col);
	}

	headers.append(GridColumnConfig("test", "bool测试"));
	headers.append(GridColumnConfig("test2", "double测试"));

	auto* model = new GenericTableModel<Patient>(headers, this);

	model->clear();

	// 添加测试数据
	model->addItem(new Patient(1, "张三", "male", 35, "MR2023001", QDate(1988, 5, 15),
	                           "13800138000", "北京市海淀区", "A型", "青霉素过敏", "高血压"));
	model->addItem(new Patient(2, "李四", "female", 28, "MR2023002", QDate(1995, 8, 20),
	                           "13900139000", "上海市浦东新区", "B型", "无", "无"));
	model->addItem(new Patient(3, "王五", "male", 42, "MR2023003", QDate(1981, 3, 10),
	                           "13700137000", "广州市天河区", "O型", "头孢过敏", "糖尿病"));
	model->addItem(new Patient(4, "赵六", "male", 42, "MR2023004", QDate(1981, 3, 10),
	                           "13700137001", "广州市天河区", "O型", "头孢过敏", "糖尿病"));
	model->addItem(new Patient(5, "钱七", "female", 35, "MR2023005", QDate(1988, 5, 15),
	                           "13700137002", "深圳市南山区", "A型", "无", "高血压"));
	model->addItem(new Patient(6, "孙八", "male", 35, "MR2023006", QDate(1988, 6, 20),
	                           "13700137003", "北京市朝阳区", "B型", "无", "哮喘"));
	model->addItem(new Patient(7, "周九", "female", 42, "MR2023007", QDate(1981, 7, 1),
	                           "13600136000", "上海市徐汇区", "O型", "青霉素过敏", "糖尿病"));
	model->addItem(new Patient(8, "吴十", "male", 50, "MR2023008", QDate(1973, 2, 12),
	                           "13500135000", "广州市越秀区", "AB型", "无", "高血压"));
	model->addItem(new Patient(9, "郑十一", "female", 50, "MR2023009", QDate(1973, 3, 30),
	                           "13400134000", "北京市朝阳区", "AB型", "无", "糖尿病"));
	model->addItem(new Patient(10, "王十二", "male", 28, "MR2023010", QDate(1995, 12, 5),
	                           "13300133000", "深圳市福田区", "A型", "无", "哮喘"));
	model->addItem(new Patient(11, "冯十三", "female", 28, "MR2023011", QDate(1995, 11, 11),
	                           "13200132000", "上海市浦东新区", "B型", "无", "高血压"));
	model->addItem(new Patient(12, "陈十四", "male", 35, "MR2023012", QDate(1988, 4, 22),
	                           "13100131000", "北京市海淀区", "A型", "无", "糖尿病"));
	model->addItem(new Patient(13, "褚十五", "female", 35, "MR2023013", QDate(1988, 8, 16),
	                           "13000130000", "深圳市南山区", "O型", "青霉素过敏", "哮喘"));
	model->addItem(new Patient(14, "卫十六", "male", 42, "MR2023014", QDate(1981, 1, 8),
	                           "12900129000", "广州市天河区", "B型", "无", "高血压"));
	model->addItem(new Patient(15, "蒋十七", "female", 50, "MR2023015", QDate(1973, 10, 20),
	                           "12800128000", "北京市海淀区", "O型", "无", "糖尿病"));

	cxiTable->setModel(model);
	cxiTable->setColumnConfigs(headers);

	connect(ui->btn_addFilter, &QPushButton::clicked, [this, cxiTable]() {
		auto column = ui->line_column->text().toInt();
		auto condition = ui->line_condition->text();
		cxiTable->onFilter(column, condition);
	});
	connect(ui->btn_clear, &QPushButton::clicked, [this, cxiTable]() {
		cxiTable->clearFilter();
	});

	connect(ui->add_group_btn, &QPushButton::clicked, [this, cxiTable]() {
		QList<cxitable::GroupConfig> configs;
		configs.append({2, "标题：${title}，数据：${data}，数据量：${count}"});
		configs.append({3, "【${title}=${data}】共${count}条"});
		configs.append({8, "${title}:${data} (${count})"});
		cxiTable->addGroups(configs);
		cxiTable->groupExpanded();
	});

	connect(ui->del_group_btn, &QPushButton::clicked, [this, cxiTable]() {
		// cxiTable->removeGroups()、
		cxiTable->removeGroups(QList<int>{2, 3, 8});
	});

	connect(ui->collse_btn, &QPushButton::clicked, [this, cxiTable]() {
		cxiTable->collapseAll();
	});
	connect(ui->expand_btn, &QPushButton::clicked, [this, cxiTable]() {
		cxiTable->expandAll();
	});
}

void TableWidget::initPropertySystem()
{
	auto window = new QWidget(this);
	window->setWindowTitle("表格样式全设置（树形结构）");

	auto* layout = new QVBoxLayout(window);
	auto propertyBrowser = new QtTreePropertyBrowser(window);
	layout->addWidget(propertyBrowser);

	// ==================== 通用属性管理器初始化 ====================
	// 1. 创建所有需要的管理器（复用，不再重复创建）
	auto colorManager = new QtColorPropertyManager(window);
	auto fontManager = new QtFontPropertyManager(window);
	auto boolManager = new QtBoolPropertyManager(window);
	auto enumManager = new QtEnumPropertyManager(window);
	auto intManager = new QtIntPropertyManager(window);
	auto stringManger = new QtStringPropertyManager(window);
	auto doubleManager = new QtDoublePropertyManager(window);

	// 2. 创建对应的编辑器工厂（复用，不再重复创建）
	auto colorFactory = new QtColorEditorFactory(window);
	auto fontFactory = new QtFontEditorFactory(window);
	auto checkBoxFactory = new QtCheckBoxFactory(window);
	auto enumFactory = new QtEnumEditorFactory(window);
	auto* spinBoxFactory = new QtSpinBoxFactory(window);
	auto stringFactory = new QtLineEditFactory(window);
	auto* doubleFactory = new QtDoubleSpinBoxFactory(window);

	// 3. 为属性浏览器设置工厂（一次性设置，后续分组直接复用）
	propertyBrowser->setFactoryForManager(colorManager, colorFactory);
	propertyBrowser->setFactoryForManager(fontManager, fontFactory);
	propertyBrowser->setFactoryForManager(boolManager, checkBoxFactory);
	propertyBrowser->setFactoryForManager(enumManager, enumFactory);
	propertyBrowser->setFactoryForManager(intManager, spinBoxFactory);
	propertyBrowser->setFactoryForManager(stringManger, stringFactory);
	propertyBrowser->setFactoryForManager(doubleManager, doubleFactory);

	// =================== 建立信号与槽的连接 =====================
	connect(intManager, &QtIntPropertyManager::valueChanged, this, &TableWidget::onIntPropertyChanged);
	connect(boolManager, &QtBoolPropertyManager::valueChanged, this, &TableWidget::onBoolPropertyChanged);
	connect(enumManager, &QtEnumPropertyManager::valueChanged, this, &TableWidget::onEnumPropertyChanged);
	connect(colorManager, &QtColorPropertyManager::valueChanged, this, &TableWidget::onColorPropertyChanged);
	connect(fontManager, &QtFontPropertyManager::valueChanged, this, &TableWidget::onFontPropertyChanged);
	connect(doubleManager, &QtDoublePropertyManager::valueChanged, this, &TableWidget::onDoublePropertyChanged);
	connect(stringManger, &QtStringPropertyManager::valueChanged, this, &TableWidget::onStringPropertyChanged);

	// ==================== 具体属性配置（此处目前脱离实际接口，等有实际接口后再修改) ====================
	// -------------------------- 1. 颜色设置分组 --------------------------
	QtGroupPropertyManager* colorGroupManager = new QtGroupPropertyManager(window);
	QtProperty* colorGroup = colorGroupManager->addProperty("1. 颜色设置");

	QtProperty* rowFgColor = colorManager->addProperty("行前景色1");
	colorManager->setValue(rowFgColor, QColor(0, 0, 0));
	QtProperty* rowBgColor = colorManager->addProperty("行背景色");
	colorManager->setValue(rowBgColor, QColor(255, 255, 255));
	colorGroup->addSubProperty(rowFgColor);
	colorGroup->addSubProperty(rowBgColor);
	propertyBrowser->addProperty(colorGroup);
	// 注册颜色属性处理器
	registerPropertyHandler<QColor>(rowFgColor->propertyName(), [this](const QVariant& v) {
		// ui->cxiTable->setColor(v.value<QColor>());  // 后续补充具体逻辑
		ui->log_text->append("行前景色");
	});

	registerPropertyHandler<QColor>(rowBgColor->propertyName(), [this](const QVariant& v) {
		// ui->cxiTable->setColor(v.value<QColor>());  // 后续补充具体逻辑
		ui->log_text->append("行背景色");
	});


	// -------------------------- 2. 字体设置分组 --------------------------
	QtGroupPropertyManager* fontGroupManager = new QtGroupPropertyManager(window);
	QtProperty* fontGroup = fontGroupManager->addProperty("2. 字体设置");

	QtProperty* tableFont = fontManager->addProperty("表格字体");
	QFont defaultFont;
	defaultFont.setPointSize(16);// 默认大小16px（pointSize与px近似，根据系统适配）
	defaultFont.setFamily("SimHei");// 默认字体（黑体）
	fontManager->setValue(tableFont, defaultFont);
	fontGroup->addSubProperty(tableFont);
	propertyBrowser->addProperty(fontGroup);
	// 注册字体属性处理器
	registerPropertyHandler<QFont>("表格字体", [this](const QVariant& v) {
		// ui->cxiTable->setFont(v.value<QFont>());  // 后续补充具体逻辑
		ui->log_text->append("这是测试字体");
	});

	// -------------------------- 3. 标题设置分组（从testProperty迁移） --------------------------
	QtGroupPropertyManager* titleGroupManager = new QtGroupPropertyManager(window);
	QtProperty* titleGroup = titleGroupManager->addProperty("3. 标题设置");

	// 3.1 标题是否显示（布尔值→复选框）
	QtProperty* titleVisible = boolManager->addProperty("标题是否显示");
	boolManager->setValue(titleVisible, true);// 默认显示
	// 3.2 标题对齐方式（枚举→下拉框）
	QtProperty* titleAlign = enumManager->addProperty("标题对齐方式");
	enumManager->setEnumNames(titleAlign, QStringList() << "靠左" << "靠右");
	enumManager->setValue(titleAlign, 0);// 默认靠左

	titleGroup->addSubProperty(titleVisible);
	titleGroup->addSubProperty(titleAlign);
	propertyBrowser->addProperty(titleGroup);
	// 注册标题属性处理器
	registerPropertyHandler<bool>("标题是否显示", [this](const QVariant& v) {
		// ui->cxiTable->setTitleVisible(v.toBool());  // 后续补充具体逻辑
		ui->log_text->append("标题是否显示");
	});
	registerPropertyHandler<int>("标题对齐方式", [this](const QVariant& v) {
		// ui->cxiTable->setTitleAlignment(v.toInt());  // 后续补充具体逻辑
		ui->log_text->append("标题对齐方式");
	});

	// -------------------------- 4. 行头设置分组（从testProperty迁移） --------------------------
	QtGroupPropertyManager* rowHeaderGroupManager = new QtGroupPropertyManager(window);
	QtProperty* rowHeaderGroup = rowHeaderGroupManager->addProperty("4. 行头设置");

	// 4.1 行头是否显示
	QtProperty* rowHeaderVisible = boolManager->addProperty("是否显示行头");
	boolManager->setValue(rowHeaderVisible, true);// 默认显示
	// 4.2 行头是否显示数字序号
	QtProperty* rowHeaderShowNumber = boolManager->addProperty("行头是否显示序号");
	boolManager->setValue(rowHeaderShowNumber, true);// 默认显示

	rowHeaderGroup->addSubProperty(rowHeaderVisible);
	rowHeaderGroup->addSubProperty(rowHeaderShowNumber);
	propertyBrowser->addProperty(rowHeaderGroup);
	// 注册行头属性处理器
	registerPropertyHandler<bool>("是否显示行头", [this](const QVariant& v) {
		// ui->cxiTable->setRowHeaderVisible(v.toBool());  // 后续补充具体逻辑
		ui->log_text->append("是否显示行头");
	});
	registerPropertyHandler<bool>("行头是否显示序号", [this](const QVariant& v) {
		// ui->cxiTable->setRowHeaderShowNumber(v.toBool());  // 后续补充具体逻辑
		ui->log_text->append("行头是否显示序号");
	});

	// -------------------------- 5. 边框与分割线设置分组（从testProperty迁移） --------------------------
	QtGroupPropertyManager* borderGroupManager = new QtGroupPropertyManager(window);
	QtProperty* borderGroup = borderGroupManager->addProperty("5. 边框与分割线设置");

	// 5.1 表格边框显示样式（枚举）
	QtProperty* tableBorderStyle = enumManager->addProperty("表格边框显示样式");
	enumManager->setEnumNames(tableBorderStyle, QStringList()
	                                            << "无边框"
	                                            << "仅上边框"
	                                            << "仅下边框"
	                                            << "仅左边框"
	                                            << "仅右边框"
	                                            << "上下边框"
	                                            << "左右边框"
	                                            << "所有边框");
	enumManager->setValue(tableBorderStyle, 7);// 默认显示所有边框
	// 5.2 分割线颜色（复用colorManager）
	QtProperty* splitLineColor = colorManager->addProperty("分割线颜色");
	colorManager->setValue(splitLineColor, QColor(200, 200, 200));
	// 5.3 分割线宽度（整数→数值输入框，范围1-10）
	QtProperty* splitLineWidth = intManager->addProperty("分割线宽度（px）");
	intManager->setValue(splitLineWidth, 1);// 默认1px
	intManager->setRange(splitLineWidth, 1, 10);
	// 5.4 指定分割列（0表示不指定）
	QtProperty* splitColumn = intManager->addProperty("指定分割列（0=不指定）");
	intManager->setValue(splitColumn, 0);// 默认不指定
	intManager->setMinimum(splitColumn, 0);

	borderGroup->addSubProperty(tableBorderStyle);
	borderGroup->addSubProperty(splitLineColor);
	borderGroup->addSubProperty(splitLineWidth);
	borderGroup->addSubProperty(splitColumn);
	propertyBrowser->addProperty(borderGroup);
	// 注册边框属性处理器
	registerPropertyHandler<int>("表格边框显示样式", [this](const QVariant& v) {
		// ui->cxiTable->setBorderStyle(v.toInt());  // 后续补充具体逻辑
		ui->log_text->append("表格边框显示样式：" + QString::number(v.toInt()));
	});
	registerPropertyHandler<QColor>("分割线颜色", [this](const QVariant& v) {
		// ui->cxiTable->setSplitLineColor(v.value<QColor>());  // 后续补充具体逻辑
		ui->log_text->append("分割线颜色：" + v.value<QColor>().name());
	});
	registerPropertyHandler<int>("分割线宽度（px）", [this](const QVariant& v) {
		// ui->cxiTable->setSplitLineWidth(v.toInt());  // 后续补充具体逻辑
		ui->log_text->append("分割线宽度：" + QString::number(v.toInt()));
	});
	registerPropertyHandler<int>("指定分割列（0=不指定）", [this](const QVariant& v) {
		// ui->cxiTable->setSplitColumn(v.toInt());  // 后续补充具体逻辑
		ui->log_text->append("指定分割列：" + QString::number(v.toInt()));
	});

	// -------------------------- 6. 列显示样式设置分组（从testProperty迁移） --------------------------
	QtGroupPropertyManager* columnStyleGroupManager = new QtGroupPropertyManager(window);
	QtProperty* columnStyleGroup = columnStyleGroupManager->addProperty("6. 列显示样式设置");

	QtProperty* columnStyle = enumManager->addProperty("列显示模式");
	enumManager->setEnumNames(columnStyle, QStringList()
	                                       << "1. 显示所有列，超出部分滚动"
	                                       << "2. 可视区域内自动调整（超出滚动）"
	                                       << "3. 所有列适配可视区域"
	                                       << "4. 最后一列扩展适配可视区域");
	enumManager->setValue(columnStyle, 0);// 默认模式1

	columnStyleGroup->addSubProperty(columnStyle);
	propertyBrowser->addProperty(columnStyleGroup);
	// 注册列显示样式处理器
	registerPropertyHandler<int>("列显示模式", [this](const QVariant& v) {
		// ui->cxiTable->setColumnDisplayMode(v.toInt());  // 后续补充具体逻辑
		ui->log_text->append("列显示模式：" + QString::number(v.toInt()));
	});

	// -------------------------- 7. 滚动条设置分组（从testProperty迁移） --------------------------
	QtGroupPropertyManager* scrollGroupManager = new QtGroupPropertyManager(window);
	QtProperty* scrollGroup = scrollGroupManager->addProperty("7. 滚动条设置");

	QtProperty* scrollStyle = enumManager->addProperty("滚动条行为");
	enumManager->setEnumNames(scrollStyle, QStringList()
	                                       << "1. 跟踪时不滚动，释放后滚动（显示提示）"
	                                       << "2. 跟踪时立即滚动（无提示）");
	enumManager->setValue(scrollStyle, 1);// 默认模式2

	scrollGroup->addSubProperty(scrollStyle);
	propertyBrowser->addProperty(scrollGroup);
	// 注册滚动条处理器
	registerPropertyHandler<int>("滚动条行为", [this](const QVariant& v) {
		// ui->cxiTable->setScrollBehavior(v.toInt());  // 后续补充具体逻辑
		ui->log_text->append("滚动条行为：" + QString::number(v.toInt()));
	});

	// -------------------------- 8. 删除线设置分组（从testProperty迁移） --------------------------
	QtGroupPropertyManager* strikeLineGroupManager = new QtGroupPropertyManager(window);
	QtProperty* strikeLineGroup = strikeLineGroupManager->addProperty("8. 删除线设置");

	// 8.1 删除线颜色（复用colorManager）
	QtProperty* strikeLineColor = colorManager->addProperty("删除线颜色");
	colorManager->setValue(strikeLineColor, QColor(255, 0, 0));// 默认红色
	// 8.2 删除线宽度（复用intManager，范围1-5）
	QtProperty* strikeLineWidth = intManager->addProperty("删除线宽度（px）");
	intManager->setValue(strikeLineWidth, 2);// 默认2px
	intManager->setRange(strikeLineWidth, 1, 5);

	strikeLineGroup->addSubProperty(strikeLineColor);
	strikeLineGroup->addSubProperty(strikeLineWidth);
	propertyBrowser->addProperty(strikeLineGroup);
	// 注册删除线处理器
	registerPropertyHandler<QColor>("删除线颜色", [this](const QVariant& v) {
		// ui->cxiTable->setStrikeLineColor(v.value<QColor>());  // 后续补充具体逻辑
		ui->log_text->append("删除线颜色：" + v.value<QColor>().name());
	});
	registerPropertyHandler<int>("删除线宽度（px）", [this](const QVariant& v) {
		// ui->cxiTable->setStrikeLineWidth(v.toInt());  // 后续补充具体逻辑
		ui->log_text->append("删除线宽度：" + QString::number(v.toInt()));
	});

	// ==================== 树形结构默认折叠 ====================
	QList<QtBrowserItem*> items = propertyBrowser->topLevelItems();
	for (QtBrowserItem* item: items)
	{
		propertyBrowser->setExpanded(item, false);
	}

	// ==================== 关联到DockWidget ====================
	ui->dockWidget_property->setWidget(window);
}

void TableWidget::appendLogAndSelect(const QString& text)
{
	ui->log_text->append(text);
	QTextCursor cursor = ui->log_text->textCursor();
	cursor.movePosition(QTextCursor::End);
	cursor.select(QTextCursor::LineUnderCursor);
	ui->log_text->setTextCursor(cursor);
	ui->log_text->ensureCursorVisible();
}

void TableWidget::handlePropertyChanged(QtProperty* property, const QString& valueStr)
{
	QString name = property->propertyName();
	if (m_propertyHandlers.contains(name))
	{
		m_propertyHandlers[name](valueStr);// 回调函数接收 QString
		appendLogAndSelect(QString("时间：%1 属性名称：%2，属性值：%3")
				.arg(QDateTime::currentDateTime().toString("HH:mm:ss"))
				.arg(name)
				.arg(valueStr));
	}
}

void TableWidget::onIntPropertyChanged(QtProperty* property, int value)
{
	handlePropertyChanged(property, QString::number(value));
}

void TableWidget::onBoolPropertyChanged(QtProperty* property, bool value)
{
	handlePropertyChanged(property, value ? "true" : "false");
}

void TableWidget::onEnumPropertyChanged(QtProperty* property, int value)
{
	handlePropertyChanged(property, QString::number(value));
}

void TableWidget::onColorPropertyChanged(QtProperty* property, const QColor& value)
{
	LOG_INFO("颜色发生改变");
	handlePropertyChanged(property, value.name());
}

void TableWidget::onFontPropertyChanged(QtProperty* property, const QFont& value)
{
	handlePropertyChanged(property, value.toString());
}

void TableWidget::onStringPropertyChanged(QtProperty* property, const QString& value)
{
	handlePropertyChanged(property, value);
}

void TableWidget::onDoublePropertyChanged(QtProperty* property, double value)
{
	handlePropertyChanged(property, QString::number(value));
}

void TableWidget::_init()
{
	initStyle();
	initDefaultTable();
	initPropertySystem();
	// testProperty();
}

void TableWidget::initStyle()
{
	ui->splitter->setHandleWidth(6);
	ui->splitter->setStretchFactor(0, 8);
	ui->splitter->setStretchFactor(1, 2);
	ui->splitter->setStyleSheet(R"(
        QSplitter::handle {
            background-color: #b0b0b0;
            border: 1px solid #707070;
        }
        QSplitter::handle:horizontal {
            width: 6px;
        }
    )");
}